#include "spscaleadaptor.h"
#include <QDebug>
//#include <TSettings>
#include "common/tsettings/tsettings.h"
#include "common/common.h"
#include "common/floatcompara.h"
#include "common/gui/mymessagedialog.h"
#define MINWGT 5

const char* SpScaleAdaptor::WEIGHING_UNIT = "UNIT";
const char* SpScaleAdaptor::WEIGHING_DECI = "DECI";
const char* SpScaleAdaptor::WEIGHING_MAX = "MAX";
const char* SpScaleAdaptor::WEIGHING_DIVI = "DIVI";

const char* SpScaleAdaptor::WEIGHING_ADW = "ADW";
//const char* SpScaleAdaptor::WEIGHING_ZERO = "ZERO";
const char* SpScaleAdaptor::WEIGHING_HZERO = "HZERO";
const char* SpScaleAdaptor::WEIGHING_AUTOZEROTRACE = "AZEROT";
const char* SpScaleAdaptor::WEIGHING_AUTOZERORANGE = "AZEROR";
//const char* SpScaleAdaptor::CALI_AUTOZEROTRACE_SW = "AZEROSW";
//const char* SpScaleAdaptor::CALI_AUTOZERORANGE = "AZEROR";
//const char* SpScaleAdaptor::CALI_BOOTAUTOZERO_SW = "SZEROSW";
//const char* SpScaleAdaptor::CALI_BOOTAUTORANGE = "SZEROR";

SpScaleAdaptor* SpScaleAdaptor::mSsp = NULL;
const SpScaleAdaptor::CmdHandler SpScaleAdaptor::cmdTable[] =
{
    {"SS",&SpScaleAdaptor::handleScaleStatus},//SS#UNIT#0|DECI#0|MAX#....\r\n
    //{"OK",&SpScaleAdaptor::handleOK},
    {"INPUT",&SpScaleAdaptor::handleInput},//INPUT#NUM#VALUE NUM=input号
    {"WGT",&SpScaleAdaptor::handleWeight},//WGT#ST(US/OL),GS(NT),(-)123.56\r\n.....
    //{"+ok",&SpScaleAdaptor::handle4Gcmd},
    {0,0}
};
const char* SpScaleAdaptor::unitTab[] = {"kg","g","斤","磅"};
const char* SpScaleAdaptor::hzeroTab[] = {"关","±2%","±10%","±20%","±50%","±100%"};
const char* SpScaleAdaptor::autoZTTab[] = {"关","0.5d","1d","2d","3d","4d","5d","6d","7d","8d"};
const char* SpScaleAdaptor::autoSZRTab[] = {"关","±10%","±20%","±50%","±100%"};
const QStringList SpScaleAdaptor::unitList = QStringList()<<"kg"<<"g"<<"斤"<<"磅";
const QStringList SpScaleAdaptor::diviList = QStringList()<<"1"<<"2"<<"5"<<"10"<<"20"<<"50"<<"100";
const QStringList SpScaleAdaptor::deciList = QStringList()<<"0"<<"1"<<"2"<<"3"<<"4";
//const QStringList SpScaleAdaptor::zeroList = QStringList()<<"1d"<<"2d"<<"3d"<<"4d"<<"5d"<<"6d";
//const QStringList SpScaleAdaptor::hzeroList = QStringList()<<"关"<<"±2%"<<"±10%"<<"±20%"<<"±50%"<<"±100%";
//const QStringList SpScaleAdaptor::autoZTList = QStringList()<<"关"<<"0.5d"<<"1d"<<"2d"<<"3d"<<"4d"<<"5d"<<"6d"<<"7d"<<"8d";
//const QStringList SpScaleAdaptor::autoSZRList = QStringList()<<"关"<<"±10%"<<"±20%"<<"±50%"<<"±100%";
const int SpScaleAdaptor::expTab[] = {1,10,100,1000,10000};

SpScaleAdaptor::SpScaleAdaptor(const QString& portName,QObject *parent):IScaleAdaptor(parent),mStrTare("0"),mOverLoad(false)
  ,mStrNet("0"),mStrGross("0"),mStab(false),mTare_g(0)
{qDebug()<<unitList;
    mCom = new QSerialPort(portName,parent);
    if(!mCom->open(QIODevice::ReadWrite))
    {
        qDebug()<<mCom->error();
        return;
    }
    mCom->setBaudRate(QSerialPort::Baud9600);
    mCom->setDataBits(QSerialPort::Data8);
    mCom->setParity(QSerialPort::NoParity);
    mCom->setFlowControl(QSerialPort::NoFlowControl);
    mCom->setStopBits(QSerialPort::OneStop);
    mErrTimer = new QTimer();
    mErrTimer->setSingleShot(true);
    mErrTimer->setInterval(2000);
    connect(mErrTimer,SIGNAL(timeout()),this,SLOT(onErrTimeOut()));
    connect(mCom,SIGNAL(readyRead()),this,SLOT(onRead()));
}

bool SpScaleAdaptor::handleReciveData(QByteArray &data)
{//qDebug()<<"handleReciveData"<<data;
    const CmdHandler *handler = &cmdTable[0];
    while(handler->cmd!=NULL)
    {
        if(data.startsWith(handler->cmd)){
            data.remove(0,strlen(handler->cmd)+1);

            if(handler->handle!=NULL){
                return (this->*(handler->handle))(data);
            }else{
                return false;
            }
        }
        handler++;
    }
    return false;
}

void SpScaleAdaptor::writeCmd(const QString &str)
{   qDebug()<<str;
    mCom->write(str.toLatin1());
}

void SpScaleAdaptor::setScale(const QString &head, const QString &data)//参数设置都直接调用此函数
{
    writeCmd(head+data+"\r\n");
    if(mErrTimer->isActive())
        mErrTimer->stop();
    mErrTimer->start();qDebug()<<"timer start";
}

void SpScaleAdaptor::tareScale(float weight)
{    
    QString str("#T#");
    setScale(str,QString::number(weight));//#T#tare\r\n (tare=0)--正常去皮;(tare>0)--预扣皮;成功回 SS#T#tare\r\n
}

void SpScaleAdaptor::zeroScale()
{
    QString str("#Z#");//成功回 SS#Z#\r\n
    setScale(str,"");
    mTare_g = 0;
    mStrTare = "0";
}

int SpScaleAdaptor::getInput(int num)
{
    QString str;
    str = QString("#STATUS#%1\r\n").arg(num);
    writeCmd(str);
}

int SpScaleAdaptor::setOutput(int num, int val)
{
    QString str;
    str = QString("#OUT#%1#%2\r\n").arg(num).arg(val);//成功回 SS#OUT\r\n
    writeCmd(str);
}

//void SpScaleAdaptor::setUnit(const QString &data)
//{
//    QString setCmd = "#UNIT#";
//    setCmd.append(data).append("\r\n");//#UNIT#1\r\n;
//    writeCmd(setCmd);
//    qDebug()<<setCmd;
//}

QString SpScaleAdaptor::getUnit()
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    return QString(unitTab[set.value(WEIGHING_UNIT,0).toInt()])/*unitList.at(set.value(WEIGHING_UNIT,0).toInt())*/;
}

int SpScaleAdaptor::getUnitIndex()
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    return set.value(WEIGHING_UNIT,0).toInt();//0--kg,1--g,2--斤,3--磅
}

//void SpScaleAdaptor::setMax(const QString &data)
//{
//    QString setCmd="#MAX#";
//    setCmd.append(data).append("\r\n");//#MAX#500\r\n;
//    writeCmd(setCmd);
//    qDebug()<<setCmd;
//}

float SpScaleAdaptor::getMax()
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
//    int unitIndex = getUnitIndex();
//    switch (unitIndex) {
//    case 0:
//        return set.value(WEIGHING_MAX,50).toFloat();
//        break;
//    case 1:
//        return set.value(WEIGHING_MAX,50).toFloat()*1000;
//        break;
//    case 2:
//        return set.value(WEIGHING_MAX,50).toFloat()*2;
//        break;
//    case 3:
//        return set.value(WEIGHING_MAX,50).toFloat()*2.2;
//        break;
//    default:
//        break;
//    }
    return set.value(WEIGHING_MAX,50).toFloat();
}

QString SpScaleAdaptor::getMaxStr()
{
    //TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    //return set.value(WEIGHING_MAX,5000).toString();
    qDebug()<<"max"<<getMax();
    return QString::number(getMax());
}

QString SpScaleAdaptor::getMaxkgStr()
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    int unitIndex = getUnitIndex();
    switch (unitIndex) {
    case 0:
        return QString::number(set.value(WEIGHING_MAX,50).toFloat());
        break;
    case 1:
        return QString::number(set.value(WEIGHING_MAX,50).toFloat()/1000);
        break;
    case 2:
        return QString::number(set.value(WEIGHING_MAX,50).toFloat()/2);
        break;
    case 3:
        return QString::number(set.value(WEIGHING_MAX,50).toFloat()/2.2);
        break;
    default:
        break;
    }
}

//void SpScaleAdaptor::setDeci(const QString &data)
//{
//    QString setCmd="#DECI#";
//    setCmd.append(data).append("\r\n");//#DECI#0\r\n;
//    writeCmd(setCmd);
//    qDebug()<<setCmd;
//}

int SpScaleAdaptor::getDeci()
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    return set.value(WEIGHING_DECI,0).toInt();
}

//void SpScaleAdaptor::setDivi(const QString &data)
//{
//    QString setCmd="#DIVI#";
//    setCmd.append(data).append("\r\n");//#DIVI#1\r\n;
//    writeCmd(setCmd);
//    qDebug()<<setCmd;
//}

int SpScaleAdaptor::getDivi()
{    
    return diviList.at(getDiviIndex()).toInt();//0--1,1--2...
}

QString SpScaleAdaptor::getDiviStr()
{
    return QString::number(getDivi());
}

int SpScaleAdaptor::getDiviIndex()
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    return set.value(WEIGHING_DIVI,0).toInt();
}

//void SpScaleAdaptor::setZero(const QString &data)
//{
//    QString setCmd = "#ZERO#";
//    setCmd.append(data).append("\r\n");//#ZERO#1\r\n;
//    writeCmd(setCmd);
//    qDebug()<<setCmd;
//}

//int SpScaleAdaptor::getZero()
//{
//    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
//    return set.value(WEIGHING_ZERO,1).toInt();//1--1d
//}

int SpScaleAdaptor::getHZero()
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    return set.value(WEIGHING_HZERO,0).toInt();//0--关，1--2%，2--10%，3--20%，4--50%，5--100%
}

QString SpScaleAdaptor::getHZeroStr()
{
    return QString(hzeroTab[getHZero()]);
}

int SpScaleAdaptor::getAutoZeroTrace()
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    return set.value(WEIGHING_AUTOZEROTRACE,0).toInt();
}

QString SpScaleAdaptor::getAutoZeroTraceStr()
{
    return QString(autoZTTab[getAutoZeroTrace()]);
}

int SpScaleAdaptor::getAutoZeroRange()
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    return set.value(WEIGHING_AUTOZERORANGE,0).toInt();
}

QString SpScaleAdaptor::getAutoZeroRangeStr()
{
    return QString(autoSZRTab[getAutoZeroRange()]);
}

QStringList SpScaleAdaptor::getUnitList1()
{
    QStringList list;
    for(auto str:unitTab) {
        list<<str;
    }
    return list;
}

QStringList SpScaleAdaptor::getHZeroList()
{
    QStringList list;
    for(auto str:hzeroTab) {
        list<<str;
    }
    return list;
}

QStringList SpScaleAdaptor::getAutoZTList()
{
    QStringList list;
    for(auto str:autoZTTab) {
        list<<str;
    }
    return list;
}

QStringList SpScaleAdaptor::getAutoSZRList()
{
    QStringList list;
    for(auto str:autoSZRTab) {
        list<<str;
    }
    return list;
}

float SpScaleAdaptor::getAdw()
{
    TSettings set(DIR_SETTINGS,TSettings::IniFormat);
    return set.value(WEIGHING_ADW,getMax()).toFloat();
}

bool SpScaleAdaptor::setAdw(float w)
{
    writeCmd(QString("LOAD%1").arg(w));
    return true;
}

float SpScaleAdaptor::floatFdnWgt()
{//qDebug()<<"floatFdnWgt"<<getDivi()<<expTab[getDeci()]<<getDeci();
    return (float)getDivi()/(float)expTab[getDeci()];
}

float SpScaleAdaptor::floatTare()
{
    int index = getUnitIndex();
    float tare;
    switch (index) {
    case 0:
        tare = mTare_g/1000;
        break;
    case 1:
        tare = mTare_g;
        break;
    case 2:
        tare = mTare_g/500 ;
        break;
    case 3:
        tare = mTare_g/454.5;
        break;
    default:
        break;
    }
    return tare;
}
void SpScaleAdaptor::floatTare_g(const QString& strTare,float* tare_g)
{
    int index = getUnitIndex();
    float tare = strTare.toFloat();
    switch (index) {
    case 0:
        *(tare_g) = tare*1000;
        break;
    case 1:
        *(tare_g) = tare;
        break;
    case 2:
        *(tare_g) = tare*500;
        break;
    case 3:
        *(tare_g) = tare*454.5;
        break;
    default:
        break;
    }
}


bool SpScaleAdaptor::stabFlag()
{
    return mStab;
}

bool SpScaleAdaptor::tareFlag()
{
    if(F_EZ(floatTare()))
        return false;
    else
        return true;
}

bool SpScaleAdaptor::zeroFlag()
{//qDebug()<<"zeroFlag()"<<floatNet()<<floatFdnWgt()*MINWGT;
    if(floatNet()<=floatFdnWgt()*MINWGT)//*20
    {
        //qDebug()<<"true";
        return true;
    }
    else
    {
        //qDebug()<<"false";
        return false;
    }
}

void SpScaleAdaptor::onRead()
{
    while(mCom->canReadLine())
    {
        QByteArray array = mCom->readLine();
        array.chop(2);
        handleReciveData(array);
    }

}

void SpScaleAdaptor::syncScalePara()
{
    setScale("#SS","");
//   writeCmd("#SS\r\n");
//    if(mErrTimer->isActive())
//        mErrTimer->stop();
//    mErrTimer->start();
}

void SpScaleAdaptor::onErrTimeOut()
{
    MyMessageDialog::warning(0,"错误","通讯异常,请检查！");
}


SpScaleAdaptor *SpScaleAdaptor::getInstance()
{
    if(mSsp == NULL)
    {


#if QT_VERSION > 0x050000
        mSsp = new SpScaleAdaptor("COM1");
#else
        mSsp = new SpScaleAdaptor("ttyS3");
#endif
    }
    return mSsp;
}

bool SpScaleAdaptor::handleInput(QByteArray &array)
{
    QList<QByteArray> arrlist = array.split('#');
    qDebug()<<arrlist.at(0).toInt()<<arrlist.at(1).toInt();
    emit inputCome(arrlist.at(0).toInt(),arrlist.at(1).toInt());
    return true;
}

bool SpScaleAdaptor::handleScaleStatus(QByteArray &array)
{qDebug()<<array<<"stop timer";
    if(mErrTimer->isActive()) mErrTimer->stop();
    QList<QByteArray> arrList = array.split('|');
    foreach (QByteArray arr, arrList) {
        QList<QByteArray> dataList = arr.split('#');
        if(dataList.size()>1)
        {
            if(dataList.at(0)=="T")
            {
                mStrTare = QString(dataList.at(1));qDebug()<<mStrTare;
                floatTare_g(mStrTare,&mTare_g);
                emit getTare(mStrTare);
            }
            else
            {
                TSettings set(DIR_SETTINGS,TSettings::IniFormat);
                set.setValue(QString(dataList.at(0)),dataList.at(1));//dataList.at(0)--UNIT,MAX,DECI,DIVI,ZERO,AZEROT,AZEROR;
                if(dataList.at(0)=="DECI") emit updateDeci();
            }

        }
    }
    emit setSuccess();
}

bool SpScaleAdaptor::handleWeight(QByteArray &array)
{
    qDebug()<<"wgt"<<array;
    QList<QByteArray> arrList = array.split(',');
    QByteArray stabArr = arrList.at(0);
    QByteArray netArr = arrList.at(2);

    if(stabArr=="ST")
    {
        mStab = true;
        if(mOverLoad)
            mOverLoad = false;
    }
    else if(stabArr=="US")
    {
        mStab = false;
        if(mOverLoad)
            mOverLoad = false;
    }
    else if(stabArr=="OL")
    {
        mOverLoad = true;
    }
    mStrNet = QString(netArr);
    mStrGross = QString::number(floatNet()+floatTare());
    emit updateScale();
}

bool SpScaleAdaptor::handle4Gcmd(QByteArray &array)
{
    qDebug()<<array;
}
